home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-11-16 | 19.7 KB | 732 lines | [TEXT/CWIE] |
- /*
- File: Sample.c
-
- Contains: Location Manager SDK Sample main code...
-
- Version: ALM SDK 2.0
- Package: Location Manager SDK 2.0
-
- Copyright: © 1996-1997 by Apple Computer, Inc.
- All rights reserved.
-
- Bugs?: Please include the the file and version information (from above) with
- the problem description. Developers belonging to one of the Apple
- developer programs can submit bug reports to:
-
- devsupport@apple.com
-
- */
-
- // -------------------------------------------------------------------------------------------------
-
- #include <ConditionalMacros.h>
-
- // We recommend using the most updated headers currently available; at this writing, that is
- // Universal Headers 3.0.1. More recent editions should work as well; if you want to use older
- // headers for some reason, it should be possible, but you're on your own and other parts of this
- // sample may need to change...
-
- #if !defined (UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0301)
-
- #error "Please use header files 3.0.1 or newer"
-
- #endif // updated headers...
-
- // Having gotten _that_ out of the way, let's be sure that nobody fiddled with the project
- // settings by accident...
-
- #if !TARGET_CPU_68K | TARGET_RT_MAC_CFM
-
- #error This project MUST be classic 68K!
-
- #endif // not 68K classic build
-
- // -------------------------------------------------------------------------------------------------
-
- // Module Include...
-
- #include "Sample.h"
-
- // Project Includes...
-
- #include "Utilities.h"
-
- // MacOS Includes...
-
- #define ALM_BASENAME()
- #define ALM_GLOBALS() GlobalsHandle
-
- #include <Components.h>
- #include <Fonts.h>
- #include <LocationManager.k.h>
- #include <PLStringFuncs.h>
- #include <Resources.h>
- #include <TextUtils.h>
-
- // -------------------------------------------------------------------------------------------------
-
- // Readability Constants...
-
- #define kInvalidFunction ((ComponentFunctionUPP) -1)
-
- #define kDefaultINTLresources NULL
- #define kNoSeconds false
-
- #define kAllocateMemory NULL
- #define kPlaceInFront (WindowPtr)-1
-
- #define kUseStandardFilterProc NULL
-
- // -------------------------------------------------------------------------------------------------
-
- // Local prototypes...
-
- static Boolean
- CallSupported (SInt16 selector);
- // Return true if the specified selector code is one this module supports...
- static ComponentResult
- HandleComponentManagerCall (ComponentParameters* params, SInt16 selector);
- // Dispatch a component manager call (selector < 0)...
- static ComponentResult
- HandleLocationManagerCall (ComponentParameters* params, SInt16 selector,
- Handle globals);
- // Dispatch a Location Manager specific call...
-
- // Component prototypes...
-
- static pascal ComponentResult
- Open (ComponentInstance self);
- // Initialize the modules's global variables, etc...
- static pascal ComponentResult
- Close (ComponentInstance self);
- // Deinitialize the modules's global variables...
-
- // -------------------------------------------------------------------------------------------------
-
- // Main entry point (interface as expected by component manager)...
-
- pascal ComponentResult
- main (ComponentParameters* params, Handle storage) {
-
- // We dispatch the calls from here; also, for ALM calls, we'll make sure the current
- // resource fork is ours...
-
- ComponentResult result;
- SInt16 selector = params->what;
- SInt16 svResFile = CurResFile ();
-
- if (selector < 0) {
- // Component manager request codes are negative...
- result = HandleComponentManagerCall (params, selector);
- } else {
- // ALM selectors...
- if (storage != NULL) {
- UseResFile ((**(GlobalsHandle) storage).resFile);
- } // if
- result = HandleLocationManagerCall (params, selector, storage);
- } // if
-
- UseResFile (svResFile);
-
- return result;
-
- } // main
-
- // -------------------------------------------------------------------------------------------------
-
- static Boolean
- CallSupported (SInt16 selector) {
-
- Boolean response;
-
- switch (selector) {
- case kALMGetCurrentSelect:
- case kALMSetCurrentSelect:
- case kALMCompareSettingSelect:
- case kALMDescribeSettingSelect:
- case kALMDescribeErrorSelect:
- case kALMEditSettingSelect:
- case kALMImportExportSelect:
- case kALMGetInfoSelect:
- case kALMGetScriptInfoSelect:
- response = true;
- break;
- default:
- response = false;
- break;
- } // switch
-
- return response;
-
- } // CallSupported
-
- // -------------------------------------------------------------------------------------------------
-
- static ComponentResult
- HandleComponentManagerCall (ComponentParameters* params, SInt16 selector) {
-
- ComponentResult result = (ComponentResult) noErr;
- ComponentFunctionUPP func = NULL;
-
- switch (selector) {
-
- case kComponentOpenSelect:
- func = (ComponentFunctionUPP) Open;
- break;
- case kComponentCloseSelect:
- func = (ComponentFunctionUPP) Close;
- break;
- case kComponentCanDoSelect:
- result = CallSupported (*(SInt16*) params->params);
- break;
- case kComponentVersionSelect:
- result = kModuleVersion;
- break;
- case kComponentRegisterSelect:
- result = false; // false means "yes, please register me"
- break;
- case kComponentTargetSelect :
- case kComponentUnregisterSelect :
- result = badComponentSelector;
- break;
-
- } // switch
-
- if (func != NULL) {
- result = CallComponentFunction (params, func);
- } // if
-
- return result;
-
- } // HandleComponentManagerCall
-
- // -------------------------------------------------------------------------------------------------
-
- static ComponentResult
- HandleLocationManagerCall (ComponentParameters* params, SInt16 selector, Handle globals) {
-
- ComponentResult result = (ComponentResult) noErr;
- ComponentFunctionUPP func = NULL;
-
- switch (selector) {
-
- case kALMGetCurrentSelect:
- func = (ComponentFunctionUPP) GetCurrent;
- break;
- case kALMSetCurrentSelect:
- func = (ComponentFunctionUPP) SetCurrent;
- break;
- case kALMCompareSettingSelect:
- func = (ComponentFunctionUPP) CompareSetting;
- break;
- case kALMEditSettingSelect:
- func = (ComponentFunctionUPP) EditSetting;
- break;
- case kALMDescribeSettingSelect:
- func = (ComponentFunctionUPP) DescribeSetting;
- break;
- case kALMDescribeErrorSelect:
- func = (ComponentFunctionUPP) DescribeError;
- break;
- case kALMImportExportSelect:
- func = (ComponentFunctionUPP) ImportExport;
- break;
- case kALMGetScriptInfoSelect:
- func = (ComponentFunctionUPP) GetScriptInfo;
- break;
- case kALMGetInfoSelect:
- func = (ComponentFunctionUPP) GetInfo;
- break;
- default:
- func = kInvalidFunction;
- break;
-
- } // switch
-
- if (func == kInvalidFunction) {
- result = badComponentSelector;
- } else if (func != NULL) {
- result = CallComponentFunctionWithStorage (globals, params, func);
- } // if
-
- return result;
-
- } // HandleLocationManagerCall
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- Open (ComponentInstance self) {
-
- // Keep the Open routine lightweight, and only fail in the case of dire
- // emergencies that indicate a major problem; under ALM 2.0, you might wish to return an
- // error here to quietly suppress your module from being usable--for example if you require
- // Infrared hardware found only on some models of computer--but it is generally better to
- // _succeed_ here and describe an _error_ from your GetCurrent call...
-
- OSErr err = noErr;
- GlobalsHandle globals = (GlobalsHandle) NewHandle (sizeof (Globals));
-
- if (globals != NULL) {
-
- SetComponentInstanceStorage (self, (Handle) globals);
-
- (**globals).fileCount = 0;
- (**globals).self = (Component) self;
- (**globals).resFile = OpenComponentResFile ((Component) self);
-
- err = ResError ();
-
- } else {
- err = memFullErr;
- } // if
-
- return (ComponentResult) err;
-
- } // Open
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- Close (ComponentInstance self) {
-
- OSErr err = noErr;
- GlobalsHandle globals = (GlobalsHandle) GetComponentInstanceStorage (self);
-
- if (globals != NULL) {
-
- SInt16 resFile = (**globals).resFile;
-
- if (resFile > 0) {
- CloseComponentResFile (resFile);
- (**globals).resFile = 0;
- } // if
-
- DisposeHandle ((Handle) globals);
- SetComponentInstanceStorage (self, NULL);
-
- } // if
-
- return (ComponentResult) err;
-
- } // Close
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- GetCurrent (GlobalsHandle globals, Handle setting) {
-
- OSErr err = noErr;
-
- // To get the current settings, we need to go off to the resource and make FSSpecs
- // for all of the files we care about, then read in their settings...
-
- err = ConfirmFSSpecs (globals);
-
- if (err == noErr) {
- err = ReadSetting (globals, (SettingHandle) setting);
- } // if
-
- return (ComponentResult) err;
-
- } // GetCurrent
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- SetCurrent (GlobalsHandle globals, Handle setting, ALMRebootFlags* flags) {
-
- OSErr err = noErr;
- Handle tempSetting = NewHandle (1);
-
- *flags = kALMNoChange; // Safe value...
-
- // Before we go off and change the setting, see if it's the current setting; if
- // the settings are _not_ the same, we'll assume "kALMAvailableNow" and let
- // UseSetting escalate it, based on any of the specific files...
-
- if (tempSetting != NULL) {
- err = (OSErr) GetCurrent (globals, tempSetting);
- if (err == noErr) {
- Boolean lookTheSame;
- err = CompareSetting (globals, tempSetting, setting, &lookTheSame);
- if ((err == noErr) && !lookTheSame) {
- *flags = kALMAvailableNow;
- err = UseSetting (globals, (SettingHandle) setting, flags);
- } // if
- } // if
- } else {
- err = memFullErr;
- } // if
-
- if (tempSetting != NULL) {
- DisposeHandle (tempSetting);
- } // if
-
- return (ComponentResult) err;
-
- } // SetCurrent
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- CompareSetting (GlobalsHandle globals, Handle setting1, Handle setting2, Boolean* equal) {
-
- #ifndef __SC__
- #pragma unused (globals)
- #endif // __SC__
-
- OSErr err = noErr;
- SInt8 svState1 = HGetState (setting1);
- SInt8 svState2 = HGetState (setting2);
- SettingPtr set1;
- SettingPtr set2;
-
- *equal = true;
-
- // To see if two settings are the same, all we do is compare their dates...
-
- HLock (setting1);
- HLock (setting2);
-
- set1 = (SettingPtr) *setting1;
- set2 = (SettingPtr) *setting2;
-
- do {
-
- UInt32 fileIndex;
- UInt32 fileCount = set1->fileCount;
-
- // If the settings versions are not the same, we have a problem...
-
- if (set1->version != set2->version) {
- *equal = false;
- break;
- } // if
-
- // If the number of files modified is not the same, we have a problem...
-
- if (fileCount != set2->fileCount) {
- *equal = false;
- break;
- } // if
-
- // Now, if the modification dates (or creation dates) changed, we'll take
- // that as a signal...
-
- for (fileIndex = 0; fileIndex < fileCount; fileIndex += 1) {
-
- FileInfoPtr fileInfo1;
- FileInfoPtr fileInfo2;
-
- fileInfo1 = &set1->fileInfo[fileIndex];
- fileInfo2 = &set2->fileInfo[fileIndex];
-
- if ((fileInfo1->dateModified != fileInfo2->dateModified) ||
- (fileInfo1->dateCreated != fileInfo2->dateCreated)) {
- *equal = false;
- break;
- } // if
- } // for
-
- } while (false); // Loop once...
-
- HSetState (setting2, svState2);
- HSetState (setting1, svState1);
-
- return (ComponentResult) err;
-
- } // CompareSetting
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- EditSetting (GlobalsHandle globals, Handle setting) {
-
- OSErr err = noErr;
- UInt32 savedA5;
- QDGlobals mqd; // So we can put up an alert...
- QDGlobalsPtr moduleQuickdraw = &mqd;
- DialogPtr theDialog = NULL;
-
- // In ALM 2.0, if you don't support EditSetting, the control panel will display a default
- // error message if the user tries to edit your setting. Of course, how to edit the setting
- // is entirely dependant on the content of the setting. In the case of this sample, we
- // really don't know what the meaning of the preference file is, but we can, at the very least,
- // give the user a more helpful error message...
-
- savedA5 = SetA5 ((UInt32) &moduleQuickdraw);
-
- // Initialize a QD world...
-
- InitGraf (&mqd.thePort); // always init _our_ QD structure
- InitFonts ();
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (NULL);
- InitCursor ();
-
- // Get and display the "sorry" dialog...
-
- theDialog = GetNewDialog (kEditMessageRsrcID, kAllocateMemory, kPlaceInFront);
-
- if (theDialog != NULL) {
-
- SInt16 itemHit;
- GrafPtr svPort;
-
- GetPort (&svPort);
- SetPort (theDialog);
- SetDialogDefaultItem (theDialog, kEditOpenButton);
- SetDialogCancelItem (theDialog, kEditCancelButton);
- ShowWindow (theDialog);
-
- // Loop until closed; note that, as long as we use the standard filter proc,
- // the ALM control panel will manage launches and moveable-modal things for us...
-
- do {
- ModalDialog (kUseStandardFilterProc, &itemHit);
- switch (itemHit) {
- case kEditCancelButton:
- err = userCanceledErr;
- break;
- case kEditOpenButton:
- err = LaunchApplications (launchContinue | launchNoFileFlags);
- break;
- case kEditApplyButton:
- err = GetCurrent (globals, setting);
- break;
- } // switch
- } while (itemHit != kEditCancelButton && itemHit != kEditApplyButton);
-
- DisposeDialog (theDialog);
- SetPort (svPort);
-
- } else {
-
- err = resNotFound;
-
- } // if
-
- // Restore a5...
-
- (void) SetA5 (savedA5);
-
- return (ComponentResult) err;
-
- } // EditSetting
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- DescribeSetting (GlobalsHandle globals, Handle setting, CharsHandle text) {
-
- OSErr err = noErr;
- SettingHandle theSet = (SettingHandle) setting;
- UInt32 dateMod;
- Str255 dateModStr;
- Str255 timeModStr;
- Str63 firstFileStr;
- Str255 templateStr;
-
- // Not entirely sure how to describe the settings, but we'll take the approach
- // of using the first file name and its modification date as "sufficient" info...
-
- err = ConfirmFSSpecs (globals);
-
- if (err == noErr) {
-
- SInt8 svState;
- UInt8 strSize;
-
- dateMod = (**theSet).fileInfo[0].dateModified;
-
- DateString (dateMod, shortDate, dateModStr, kDefaultINTLresources);
- TimeString (dateMod, kNoSeconds, timeModStr, kDefaultINTLresources);
- GetIndString (templateStr, kSampleMiscStrRsrcID, kSampleDescribeTemplateIdx);
-
- svState = HGetState ((Handle) globals);
- HLock ((Handle) globals);
- PLstrcpy (firstFileStr, (**globals).theFiles[0].name);
- HSetState ((Handle) globals, svState);
-
- InsParamStr ("\p^0", firstFileStr, templateStr);
- InsParamStr ("\p^1", timeModStr, templateStr);
- InsParamStr ("\p^2", dateModStr, templateStr);
-
- strSize = StrLength (templateStr);
- SetHandleSize ((Handle) text, strSize);
- err = MemError ();
- if (err == noErr) {
- BlockMoveData (&templateStr[1], *text, strSize);
- } // if
-
- } // if
-
- return (ComponentResult) err;
-
- } // DescribeSetting
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- DescribeError (GlobalsHandle globals, OSErr lastErr, Str255 errStr) {
-
- #ifndef __SC__
- #pragma unused (globals)
- #endif // __SC__
-
- OSErr err = noErr;
-
- // We're just going to be very superficial about this, and deal with a very few
- // "plain text" messages only. We could get fancy, and try to be a bit more
- // descriptive...
-
- if ((lastErr > 0) && (lastErr <= kSampleBiggestKnownIdx)) {
- GetIndString (errStr, kSampleErrStrRsrcID, lastErr);
- } else {
- err = paramErr; // Get ALM to generate default "error number" text...
- } // if
-
- return (ComponentResult) err;
-
- } // DescribeError
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- ImportExport (GlobalsHandle globals, Boolean import, Handle setting, SInt16 resRefNum) {
-
- OSErr err = noErr;
- SInt16 svResFile = CurResFile ();
-
- // Not a lot of work to do here; but if we are importing _and_ the current settings
- // on the machine match the import, we have a problem in that our mechanism doesn't
- // let us distinguish the new setting properly. It is possible that the user would
- // prefer to overwrite the existing settings, but we won't handle that case.
-
- UseResFile (resRefNum); // Need to do this if we use separate resources for import/export...
-
- // If this were a real module, your might need to grab more information from this
- // machine in order to carry the setting over to another machine; for example, the
- // extension set module that comes with ALM only stores the _name_ of an extension
- // manager set, which is good enough for using on one machine, but when that setting
- // is exported, the names of all the on/off extensions get spooled away in a separate
- // resource (which the module adds to the "resRefNum" resource fork)...
-
- if (import) {
-
- Handle tempSetting = NewHandle (1);
-
- if (tempSetting != NULL) {
- err = (OSErr) GetCurrent (globals, tempSetting);
- if (err == noErr) {
- Boolean lookTheSame;
- err = CompareSetting (globals, tempSetting, setting, &lookTheSame);
- if ((err == noErr) && lookTheSame) {
- err = kSampleImportPrefDatesIdx;
- } // if
- } // if
- } else {
- err = memFullErr;
- } // if
-
- if (tempSetting != NULL) {
- DisposeHandle (tempSetting);
- } // if
-
- } // if
-
- UseResFile (svResFile);
-
- return (ComponentResult) err;
-
- } // ImportExport
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- GetScriptInfo (GlobalsHandle globals, ALMScriptManagerInfo* info) {
-
- #ifndef __SC__
- #pragma unused (globals)
- #endif // __SC__
-
- OSErr err = noErr;
- ALMAltScriptManagerInfoHandle scriptInfo = NULL;
-
- // We stored this stuff in a resource, so it can be localized easily; we have to do a bit of
- // translation, though, from the alternate format to the ALM format (fortunately
- // the alternate format is given to us in the headers!)...
-
- scriptInfo = (ALMAltScriptManagerInfoHandle)
- GetResource (kALMAltScriptManagerInfoRsrcType, kALMAltScriptManagerInfoRsrcID);
-
- if (scriptInfo != NULL) {
-
- HLock ((Handle) scriptInfo);
-
- info->version = (**scriptInfo).version;
- info->scriptCode = (**scriptInfo).scriptCode;
- info->regionCode = (**scriptInfo).regionCode;
- info->langCode = (**scriptInfo).langCode;
- info->fontSize = (**scriptInfo).fontSize;
- GetFNum ((**scriptInfo).fontName, &info->fontNum);
-
- HUnlock ((Handle) scriptInfo);
-
- } else {
- err = ResError ();
- } // if
-
- if (scriptInfo != NULL) {
- ReleaseResource ((Handle) scriptInfo);
- } // if
-
- return (ComponentResult) err;
-
- } // GetScriptInfo
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- GetInfo (GlobalsHandle globals, CharsHandle* text, STHandle* style, ModalFilterUPP filter) {
-
- #ifndef __SC__
- #pragma unused (globals, filter)
- #endif // __SC__
-
- OSErr err = noErr;
-
- // This code is pretty cookie-cutter, unless you want to make it context-sensitive...
-
- do {
-
- *text = (CharsHandle) Get1Resource ('TEXT', kGetInfoRsrcID);
- err = ResError ();
- if (err != noErr) {
- break;
- } else if (*text == NULL) {
- err = resNotFound;
- break;
- } // if
- *style = (STHandle) Get1Resource ('styl', kGetInfoRsrcID);
- err = ResError ();
- if (err != noErr) {
- break;
- } else if (*style == NULL) {
- err = resNotFound;
- break;
- } // if
- DetachResource ((Handle) *text);
- DetachResource ((Handle) *style);
-
- } while (false); // execute once...
-
- return (ComponentResult) err;
-
- } // GetInfo
-
- // -------------------------------------------------------------------------------------------------
-